from pathlib import Path
import xml.etree.ElementTree as ET
from typing import Callable
from .pdn import PluginPDN
from .base import *
from fpowerkit import Generator
from feasytools import ComFunc

V2GRes = list[float]

class PluginV2G(PluginBase[V2GRes]):
    @property
    def Description(self)->str:
        return "V2G调度系统"
    
    def Initialization(self,elem:ET.Element,inst:TrafficInst,work_dir:Path,plugin_dependency:'list[PluginBase]')->V2GRes:
        assert len(plugin_dependency) == 1 and isinstance(plugin_dependency[0],PluginPDN), "V2G调度器依赖PDN插件"
        self.__pdn = plugin_dependency[0]
        self.__inst = inst
        self._cap:list[float] = [0.] * len(self.__pdn._pk)

        # 将慢充站V2G注册为发电机
        for i,pk in enumerate(self.__pdn._pk):
            self.__pdn.Grid.AddGen(Generator("V2G_"+pk.name,pk.node,
                0.,ComFunc(lambda t: self._get_cap(t,i)),0.,0.,0.,pk.psell*(self.__pdn.Grid.Sb*1000),0.))
        self.SetPreStep(self._work)
        return []
    
    def _get_cap(self,t:int,i:int)->float:
        if not self.IsOnline(t): return 0.0 #不在规定时间之内，不使用V2G
        return self._cap[i]
   
    def _work(self,_t:int,sta:PluginStatus)->tuple[bool,list[float]]:
        '''获取_t时刻配网所有有慢充站的母线V2G需求功率, 单位kWh/s, 3.6MW=3600kW=1kWh/s'''
        if sta == PluginStatus.EXECUTE:
            if self.__pdn.LastPreStepSucceed:
                self._cap = [x*3.6/self.__pdn.Grid.Sb for x in self.__inst.PKList.get_V2G_cap(_t)]
                f = lambda x: (0.0 if x is None else x)*self.__pdn.Grid.Sb/3.6
                ret1 = [f(self.__pdn.Grid.Gen("V2G_"+pk.name).P) for pk in self.__pdn._pk]
                if sum(ret1)>1e-8: ret = True, ret1
                else: ret = False, []
            else:
                ret = False, []
            self.__inst.PKList.set_V2G_demand(ret[1])
        elif sta == PluginStatus.OFFLINE:
            self.__inst.PKList.set_V2G_demand([])
            ret = True, []
        elif sta == PluginStatus.HOLD:
            ret = True, self.LastPreStepResult
        return ret